package mil.nga.giat.geowave.core.cli.prefix; import static org.junit.Assert.*; import java.lang.reflect.Method; import java.util.Arrays; import org.junit.Test; import javassist.CannotCompileException; import javassist.ClassPool; import javassist.CtClass; import javassist.CtField; import javassist.CtMethod; import javassist.CtNewMethod; import javassist.NotFoundException; import javassist.bytecode.AnnotationsAttribute; import javassist.bytecode.AttributeInfo; import javassist.bytecode.ClassFile; import javassist.bytecode.ConstPool; import javassist.bytecode.annotation.Annotation; import javassist.bytecode.annotation.IntegerMemberValue; import junit.framework.Assert; import mil.nga.giat.geowave.core.cli.prefix.JavassistUtils; public class JavassistUtilsTest { @Test public void testCloneAnnotationsAttribute() { CtClass clz = ClassPool.getDefault().makeClass( "testCloneAnnotationsAttribute"); CtMethod ctmethod = addNewMethod( clz, "origMethod"); AnnotationsAttribute attr = annotateMethod( ctmethod, "origAnno", 135); AnnotationsAttribute clonedAttr = JavassistUtils.cloneAnnotationsAttribute( ctmethod.getMethodInfo().getConstPool(), attr, java.lang.annotation.ElementType.METHOD); Assert.assertEquals( 135, ((IntegerMemberValue) clonedAttr.getAnnotation( "java.lang.Integer").getMemberValue( "origAnno")).getValue()); } private static class FindMethodTest { public void method1() { return; } public void methodA() { return; } } @Test public void testFindMethod() { CtClass ctclass = ClassPool.getDefault().makeClass( "testFindMethodClass"); addNewMethod( ctclass, "method1"); addNewMethod( ctclass, "method2"); Method m = null; try { m = FindMethodTest.class.getMethod("method1"); } catch (NoSuchMethodException | SecurityException e1) { e1.printStackTrace(); return; } try { CtMethod foundMethod = JavassistUtils.findMethod( ctclass, m); Assert.assertEquals( "method1", foundMethod.getName()); } catch (NotFoundException e) { e.printStackTrace(); fail("Could not find method in CtClass"); } } @Test public void testCopyClassAnnontations() { CtClass fromClass = ClassPool.getDefault().makeClass( "fromClass"); CtClass toClass = ClassPool.getDefault().makeClass( "toClass"); // Create class annotations ConstPool fromPool = fromClass.getClassFile().getConstPool(); AnnotationsAttribute attr = new AnnotationsAttribute( fromPool, AnnotationsAttribute.visibleTag); Annotation anno = new Annotation( "java.lang.Integer", fromPool); anno.addMemberValue( "copyClassName", new IntegerMemberValue( fromPool, 246)); attr.addAnnotation(anno); fromClass.getClassFile().addAttribute( attr); JavassistUtils.copyClassAnnotations( fromClass, toClass); Annotation toAnno = ((AnnotationsAttribute) toClass.getClassFile().getAttribute( AnnotationsAttribute.visibleTag)).getAnnotation("java.lang.Integer"); Assert.assertEquals( 246, ((IntegerMemberValue) toAnno.getMemberValue("copyClassName")).getValue()); } @Test public void testCopyMethodAnnotationsToField() { CtClass ctclass = ClassPool.getDefault().makeClass( "test"); CtMethod createdMethod = addNewMethod( ctclass, "doNothing"); annotateMethod( createdMethod, "value", 123); CtField createdField = addNewField( ctclass, "toField"); JavassistUtils.copyMethodAnnotationsToField( createdMethod, createdField); IntegerMemberValue i = null; for (Annotation annot : ((AnnotationsAttribute) createdField.getFieldInfo().getAttribute( AnnotationsAttribute.visibleTag)).getAnnotations()) { i = (IntegerMemberValue) annot.getMemberValue("value"); if (i != null) { break; } } if (i == null || i.getValue() != 123) { fail("Expected annotation value 123 but found " + i); } } @Test public void testGetNextUniqueClassName() { String unique1 = JavassistUtils.getNextUniqueClassName(); String unique2 = JavassistUtils.getNextUniqueClassName(); Assert.assertFalse(unique1.equals(unique2)); } @Test public void testGetNextUniqueFieldName() { String unique1 = JavassistUtils.getNextUniqueFieldName(); String unique2 = JavassistUtils.getNextUniqueFieldName(); Assert.assertFalse(unique1.equals(unique2)); } @Test public void testGenerateEmptyClass() { CtClass emptyClass = JavassistUtils.generateEmptyClass(); CtClass anotherEmptyClass = JavassistUtils.generateEmptyClass(); Assert.assertFalse(emptyClass.equals(anotherEmptyClass)); // test empty class works as expected CtMethod method = addNewMethod( emptyClass, "a"); annotateMethod( method, "abc", 7); CtField field = addNewField( emptyClass, "d"); annotateField( field, "def", 9); Assert.assertEquals( 7, ((IntegerMemberValue) ((AnnotationsAttribute) method.getMethodInfo().getAttribute( AnnotationsAttribute.visibleTag)).getAnnotation( "java.lang.Integer").getMemberValue( "abc")).getValue()); Assert.assertEquals( 9, ((IntegerMemberValue) ((AnnotationsAttribute) field.getFieldInfo().getAttribute( AnnotationsAttribute.visibleTag)).getAnnotation( "java.lang.Integer").getMemberValue( "def")).getValue()); } class TestClass { int field1; String field2; public void doNothing() { return; } } private CtMethod addNewMethod( CtClass clz, String methodName ) { CtMethod ctmethod = null; try { ctmethod = CtNewMethod.make( "void " + methodName + "(){ return; }", clz); clz.addMethod(ctmethod); } catch (CannotCompileException e) { e.printStackTrace(); } if (ctmethod == null) { fail("Could not create method"); } return ctmethod; } private AnnotationsAttribute annotateMethod( CtMethod ctmethod, String annotationName, int annotationValue ) { AnnotationsAttribute attr = new AnnotationsAttribute( ctmethod.getMethodInfo().getConstPool(), AnnotationsAttribute.visibleTag); Annotation anno = new Annotation( "java.lang.Integer", ctmethod.getMethodInfo().getConstPool()); anno.addMemberValue( annotationName, new IntegerMemberValue( ctmethod.getMethodInfo().getConstPool(), annotationValue)); attr.addAnnotation(anno); ctmethod.getMethodInfo().addAttribute( attr); return attr; } private CtField addNewField( CtClass clz, String fieldName ) { CtField ctfield = null; try { ctfield = new CtField( clz, fieldName, clz); clz.addField(ctfield); } catch (CannotCompileException e) { e.printStackTrace(); } if (ctfield == null) { fail("Could not create method"); } return ctfield; } private void annotateField( CtField ctfield, String annotationName, int annotationValue ) { AnnotationsAttribute attr = new AnnotationsAttribute( ctfield.getFieldInfo().getConstPool(), AnnotationsAttribute.visibleTag); Annotation anno = new Annotation( "java.lang.Integer", ctfield.getFieldInfo().getConstPool()); anno.addMemberValue( annotationName, new IntegerMemberValue( ctfield.getFieldInfo().getConstPool(), annotationValue)); attr.addAnnotation(anno); ctfield.getFieldInfo().addAttribute( attr); } }